package com.vibrationkeyboard.app.service

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import com.vibrationkeyboard.app.R
import com.vibrationkeyboard.app.model.SensorData
import com.vibrationkeyboard.app.processor.SignalProcessor
import kotlinx.coroutines.*
import java.util.concurrent.ConcurrentLinkedQueue

class SensorDataService : Service(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private lateinit var accelerometer: Sensor
    private lateinit var gyroscope: Sensor
    
    private val signalProcessor = SignalProcessor()
    private val dataQueue = ConcurrentLinkedQueue<SensorData>()
    
    private val serviceScope = CoroutineScope(Dispatchers.Default + SupervisorJob())
    private var dataProcessingJob: Job? = null
    
    companion object {
        private const val NOTIFICATION_ID = 1001
        private const val CHANNEL_ID = "sensor_service_channel"
        private const val SAMPLE_RATE = 100 // Hz
        private const val SAMPLE_PERIOD = 10000000L // nanoseconds (10ms for 100Hz)
    }

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
        initializeSensors()
        startDataProcessing()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        startForeground(NOTIFICATION_ID, createNotification())
        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onDestroy() {
        super.onDestroy()
        stopSensors()
        dataProcessingJob?.cancel()
        serviceScope.cancel()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "传感器数据采集",
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "用于采集加速度计和陀螺仪数据"
                setShowBadge(false)
            }
            
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun createNotification(): Notification {
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("震动键盘")
            .setContentText("正在采集传感器数据...")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setOngoing(true)
            .build()
    }

    private fun initializeSensors() {
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
        gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
        
        if (accelerometer != null) {
            sensorManager.registerListener(
                this,
                accelerometer,
                SensorManager.SENSOR_DELAY_GAME // ~50Hz, closest to 100Hz
            )
        }
        
        if (gyroscope != null) {
            sensorManager.registerListener(
                this,
                gyroscope,
                SensorManager.SENSOR_DELAY_GAME
            )
        }
    }

    private fun stopSensors() {
        sensorManager.unregisterListener(this)
    }

    private fun startDataProcessing() {
        dataProcessingJob = serviceScope.launch {
            while (isActive) {
                processSensorData()
                delay(10) // 100Hz processing rate
            }
        }
    }

    private fun processSensorData() {
        val currentTime = System.currentTimeMillis()
        val dataToProcess = mutableListOf<SensorData>()
        
        // 收集队列中的数据
        while (dataQueue.isNotEmpty() && dataToProcess.size < 100) {
            dataQueue.poll()?.let { dataToProcess.add(it) }
        }
        
        if (dataToProcess.isNotEmpty()) {
            // 发送数据到信号处理器
            signalProcessor.processSensorData(dataToProcess)
            
            // 检查是否有识别结果
            val recognitionResult = signalProcessor.getLatestRecognitionResult()
            if (recognitionResult != null) {
                // 发送广播通知主界面更新
                sendRecognitionResult(recognitionResult)
            }
        }
    }

    override fun onSensorChanged(event: SensorEvent?) {
        event?.let { sensorEvent ->
            val sensorData = SensorData.fromArray(sensorEvent.values)
            
            when (sensorEvent.sensor.type) {
                Sensor.TYPE_ACCELEROMETER -> {
                    // 发送加速度计数据到主界面
                    sendAccelerometerData(sensorData)
                }
                Sensor.TYPE_GYROSCOPE -> {
                    // 发送陀螺仪数据到主界面
                    sendGyroscopeData(sensorData)
                }
            }
            
            // 将数据加入处理队列
            dataQueue.offer(sensorData)
        }
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
        // 传感器精度变化处理
    }

    private fun sendAccelerometerData(data: SensorData) {
        val intent = Intent("SENSOR_DATA_ACCELEROMETER")
        intent.putExtra("x", data.x)
        intent.putExtra("y", data.y)
        intent.putExtra("z", data.z)
        intent.putExtra("timestamp", data.timestamp)
        sendBroadcast(intent)
    }

    private fun sendGyroscopeData(data: SensorData) {
        val intent = Intent("SENSOR_DATA_GYROSCOPE")
        intent.putExtra("x", data.x)
        intent.putExtra("y", data.y)
        intent.putExtra("z", data.z)
        intent.putExtra("timestamp", data.timestamp)
        sendBroadcast(intent)
    }

    private fun sendRecognitionResult(result: String) {
        val intent = Intent("RECOGNITION_RESULT")
        intent.putExtra("result", result)
        sendBroadcast(intent)
    }
} 